﻿using System.IO;
using System.Security.Cryptography;

namespace Oblivion.Networking.Encryptions
{
    public class AES
    {
        private readonly byte[] IV;
        private readonly byte[] Key;

        public AES(byte[] key)
        {
            Key = IV = key;
            Crypto = GenerateAES();
            encryptTransform = Crypto.CreateEncryptor();
            decryptTransform = Crypto.CreateDecryptor();
        }

        private ICryptoTransform encryptTransform { get; set; }
        private ICryptoTransform decryptTransform { get; set; }
        public Rijndael Crypto { get; set; }

        private Rijndael GenerateAES()
        {
            var cipher = new RijndaelManaged();
            cipher.Mode = CipherMode.CFB;
            cipher.Padding = PaddingMode.None;
            cipher.KeySize = 128;
            cipher.FeedbackSize = 8;
            cipher.Key = Key;
            cipher.IV = IV;
            return cipher;
        }

        public byte[] Encrypt(byte[] data)
        {
            byte[] encrypted;
            using (var ms = new MemoryStream(data, 0, data.Length, true, true))
            {
                ms.Flush();
                using (var strm = new CryptoStream(ms, encryptTransform, CryptoStreamMode.Write))
                {
                    strm.Write(data, 0, data.Length);
                }
                encrypted = ms.ToArray();
            }
            return encrypted;
        }

        public byte[] Decrypt(byte[] data)
        {
            byte[] decrypted;
            using (var ms = new MemoryStream(data, 0, data.Length, true, true))
            {
                ms.Flush();
                using (var strm = new CryptoStream(ms, decryptTransform, CryptoStreamMode.Read))
                {
                    strm.Read(data, 0, data.Length);
                }
                decrypted = ms.ToArray();
            }
            return decrypted;
        }
    }
}